<template>
  <div class="custom-upload-file-com">
    <el-button :loading="isUploading" class="upload-file-btn" type="primary">
      <el-icon>
        <UploadFilled/>
      </el-icon>
      上传文件
      <input v-if="!multiple" type="file" @change="fileUpload($event)"/>
      <input v-else multiple type="file" @change="fileUpload($event)"/>
    </el-button>
    <div class="upload-warning-tip">
      <p >最大上传大小：{{props.limitSize}} MB</p>
      <p >上传文件类型：{{props.fileTypeList.join(",")}}</p>
    </div>
    <div class="default-file-id-list" v-if="defaultFileList.length">
      <ul>
        <li :key="item" v-for="item in defaultFileList">
          <a @click="downloadFile(item)" href="javascript:void(0)">
            下载
          </a>
          <a v-if="props.showPlayBtn" class="play-btn" @click="playFile(item)" href="javascript:void(0)">
            播放
          </a>
          <a class="remove-btn" @click="deleteDefaultFileId(item)" href="javascript:void(0)">
            <el-icon><CircleClose /></el-icon>
          </a>
        </li>
      </ul>
    </div>
    <div class="upload-progress-list" v-if="progressList.length">
      <ul>
        <li :key="item._id" v-for="item in progressList">
          {{item.fileName}}<span class="file-progress">({{item.progress}})</span>
          <a v-if="props.showPlayBtn" class="play-btn" @click="playFileWithUpload(item)" href="javascript:void(0)">
            播放
          </a>
          <a class="remove-btn" @click="deleteFile(item)" href="javascript:void(0)">
            <el-icon><CircleClose /></el-icon>
          </a>
        </li>
      </ul>
    </div>
  </div>
</template>

<script setup>
import {getAccessToken, getTenantId} from "@/utils/auth";
import {updateFile2} from "@/api/infra/file";
import {getAudioDurationByFile, playAudio} from "@/utils/audio";
import axiosConfig from '@/config/axios/index';
import {download0} from "@/utils/download";
import {v4 as uuidv4} from 'uuid';
import {useAppStore} from "@/store/modules/app";
// uploadError 可能会触发多次
// uploadFinish 只会触发一次
// unvalidFile 只会触发一次
const message = useMessage();
const emits = defineEmits(["unvalidFile", "uploadFinish", "uploadSuccess", "uploadError"])
const props = defineProps({
  multiple: {
    type: Boolean,
    default: false
  },
  limitSize: {
    type: Number,
    default: 10, // 单位：MB
  },
  fileTypeList: {
    type: Array,
    default() {
      return ["mp3"];
    }
  },
  autoShowErrorMsg: {
    type: Boolean,
    default: true
  },
  defaultList: {
    type: Array,
    default() {
      return [];
    }
  },
  showPlayBtn: {
    type: Boolean,
    default: false
  }
})
const isUploading = ref(false);
const progressList = ref([]);
const errorList = ref([]);
const successList = ref([]);
const unValidList = ref([]);
const allFileList = ref([]);
const defaultFileList = ref([]);
const appStore = useAppStore();

watchEffect(()=> {
  defaultFileList.value = props.defaultList;
}, {deep: true})
function fileUpload(e) {
  let files = [...e.currentTarget.files];
  allFileList.value = files;
  e.currentTarget.value = "";
  let timestamp = +new Date();
  if(!props.multiple) {
    errorList.value.length = 0;
    successList.value.length = 0;
    unValidList.value.length = 0;
    progressList.value.length = 0;
  }

  files.forEach((file, index)=> {
    file._id =  timestamp + "_" + index + file.name;
    // 获取文件类型
    let fileType = file.name.split('.').pop().toLowerCase();
    // 判断文件类型是否在允许的类型列表中
    if (!props.fileTypeList.includes(fileType)) {
      unValidList.value.push({
        file,
        error: `[${file.name}]` + '文件类型不合法，仅支持：' + props.fileTypeList.join(",")
      });
    } else if(file.size > props.limitSize * 1024 * 1024) {
      unValidList.value.push({
        file,
        error: `[${file.name}]` + '文件大小超过限制，小于等于：' + props.limitSize + "MB"
      });
    } else {
      isUploading.value = true;
      startUpload(file);
    }
  });

  if(unValidList.length) {
    emits("unvalidFile", unValidList.value);
  }

  checkFinished();
}

function checkFinished() {
  // 所有文件处理完成
  if(errorList.value.length + unValidList.value.length +  successList.value.length === allFileList.value.length) {
    emits("uploadFinish", {
      successList: successList.value,
      errorList: errorList.value,
      unValidList: unValidList.value,
      defaultIdList: defaultFileList.value,
    });
    isUploading.value = false;
  }
}

function deleteFile(e) {
  progressList.value.splice(progressList.value.findIndex(item=> item._id === e._id));
  allFileList.value.splice(allFileList.value.findIndex(item=> item._id === e._id));

  if(errorList.value.findIndex(item=> item._id === e._id)) {
    errorList.value.splice(errorList.value.findIndex(item=> item.file._id === e._id));
  }
  if(successList.value.findIndex(item=> item._id === e._id)) {
    successList.value.splice(successList.value.findIndex(item=> item.file._id === e._id));
  }
  if(unValidList.value.findIndex(item=> item._id === e._id)) {
    unValidList.value.splice(unValidList.value.findIndex(item=> item.file._id === e._id));
  }

  checkFinished();
}

function downloadFile(item) {
  window.open(item.fileUrl);
  // 下载文件
  // let fileUrl = item.fileUrl;
  // axiosConfig.download({
  //   url: fileUrl
  // }).then(res=> {
  //   download0(res, item.fileId, res.type);
  // });
}

function playFile(item) {
  // console.log(item);
  // playAudio(item.fileUrl);
  appStore.getSimpleAudioPlayer.playAudio(item.fileUrl);
}

function playFileWithUpload(item) {
  let fileInfo = successList.value.find(e=>e.file._id === item._id);

  // playAudio(fileInfo.fileUrl);
  appStore.getSimpleAudioPlayer.playAudio(fileInfo.fileUrl);
}

function deleteDefaultFileId(fileId) {
  defaultFileList.value.splice(defaultFileList.value.findIndex(item=> item.fileId === fileId), 1);
}

function startUpload(file) {
  let formData = new FormData();
  let path = "lmrobot/audio/" + uuidv4();
  formData.append('file', file);
  formData.append('path', path);
  // 上传文件
  let options = {
    headers: {
      Authorization: 'Bearer ' + getAccessToken(),
      "tenant-id": getTenantId()
    },
    onUploadProgress: (progressEvent) => {
      const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total);
      let progressItem = progressList.value.find(e=>e._id === file._id);
      if(!progressItem) {
        progressList.value.push({
          _id: file._id,
          fileName: file.name,
          progress: percentCompleted + "%"
        });
      } else {
        progressItem.progress = percentCompleted;
      }
    }
  };
  updateFile2(formData, options).then(async e=>{
    let successItem = {
      file,
      fileUrl: e.data.fileUrl,
      fileId: e.data.fileId,
      path
    };
    if(props.fileTypeList.includes("mp3")) {
      let duration = await getAudioDurationByFile(file);

      successItem.audioDuration = duration;
    }
    successList.value.push(successItem);
    emits("uploadSuccess", successItem, successList.value);
    checkFinished();
    // 如果不是多选，并且有默认的文件，清空一下
    if(!props.multiple && defaultFileList.value.length) {
      defaultFileList.value.length = 0;
    }
  }).catch(e=> {
    errorList.value.push({
      file,
      error: e.message
    });
    progressList.value.find(e=>e._id === file._id).progress = "0%";
    checkFinished();
    if(props.autoShowErrorMsg) {
      message.error(e.message);
    }
  });
}
</script>

<style lang="scss" scoped>
.custom-upload-file-com {
  width: 100%;
  .upload-file-btn {
    position: relative;

    input {
      position: absolute;
      opacity: 0;
      width: 100%;
      height: 100%;
      left: 0px;
      top: 0px;
    }
  }

  .upload-progress-list, .default-file-id-list {
    ul {
      list-style: none;
      margin: 0;
      padding: 0px;
      .file-progress {
        margin-left: 12px;
      }
      li {
        line-height: 1.5;
        color: rgba(0, 0, 0, 0.5);
        .remove-btn {
          vertical-align: middle;
          float: right;
        }
        &:hover {
          color: #333;
        }
      }

      .play-btn {
        margin-left: 16px;
      }
    }
  }

  .upload-warning-tip {
    padding-top: 8px;
    p {
      margin: 0px;
      line-height: 1.4;
      font-size: 12px;
      color: #f56c6c;
    }
  }
}
</style>
